package com.example.social.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.social.common.BusinessException;
import com.example.social.common.JwtUtil;
import com.example.social.dto.LoginRequest;
import com.example.social.dto.RegisterRequest;
import com.example.social.dto.UserDTO;
import com.example.social.entity.User;
import com.example.social.mapper.UserMapper;
import com.example.social.security.UserDetailsImpl;
import com.example.social.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO register(RegisterRequest request) {
        // 检查用户名是否已存在
        if (lambdaQuery().eq(User::getUsername, request.getUsername()).exists()) {
            throw new BusinessException("用户名已存在");
        }

        // 创建新用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setNickname(request.getNickname());

        // 保存用户
        save(user);

        return convertToDTO(user);
    }

    @Override
    public String login(LoginRequest request) {
        // 获取用户信息
        User user = getByUsername(request.getUsername());
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new BusinessException("密码错误");
        }

        // 生成JWT令牌
        UserDetailsImpl userDetails = new UserDetailsImpl(user);
        return jwtUtil.generateToken(userDetails);
    }

    @Override
    public UserDTO getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        return convertToDTO(userDetails.getUser());
    }

    @Override
    public User getByUsername(String username) {
        return lambdaQuery()
            .eq(User::getUsername, username)
            .one();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO updateUser(User user) {
        if (user.getId() == null) {
            throw new BusinessException("用户ID不能为空");
        }

        // 获取当前用户
        User currentUser = getById(user.getId());
        if (currentUser == null) {
            throw new BusinessException("用户不存在");
        }

        // 如果要更新密码，需要验证旧密码
        if (user.getPassword() != null && !user.getPassword().isEmpty()) {
            String oldPassword = user.getOldPassword();
            if (oldPassword == null || oldPassword.isEmpty()) {
                throw new BusinessException("请输入旧密码");
            }
            
            if (!passwordEncoder.matches(oldPassword, currentUser.getPassword())) {
                throw new BusinessException("旧密码错误");
            }
            
            // 加密新密码
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }

        // 更新用户信息
        updateById(user);

        return convertToDTO(getById(user.getId()));
    }

    @Override
    public UserDTO convertToDTO(User user) {
        if (user == null) {
            return null;
        }

        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        return userDTO;
    }

    @Override
    public List<UserDTO> searchByNickname(String nickname) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .like(User::getNickname, nickname)
                .or()
                .like(User::getUsername, nickname);
        return list(wrapper).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
} 